package com.wocai.jrt.orders.action;

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.annotation.Resource;
import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.vteba.utils.common.PropsUtils;
import com.vteba.web.action.GenericAction;
import com.vteba.web.action.JsonBean;
import com.vteba.web.editer.DoubleEditor;
import com.vteba.web.editer.IntEditor;
import com.vteba.web.editer.LongEditor;
import com.vteba.web.editer.StringEditor;
import com.wocai.jrt.investor.service.spi.RiskDisclosureService;
import com.wocai.jrt.orders.bean.CallBackReqBean;
import com.wocai.jrt.orders.bean.CallbackResJsonBean;
import com.wocai.jrt.orders.model.Orders;
import com.wocai.jrt.orders.model.PaySerial;
import com.wocai.jrt.orders.service.impl.ContactThread;
import com.wocai.jrt.orders.service.spi.ContactService;
import com.wocai.jrt.orders.service.spi.OrdersService;
import com.wocai.jrt.orders.service.spi.PaySerialService;
import com.wocai.jrt.setting.model.Setting;
import com.wocai.jrt.setting.service.spi.SettingService;
import com.wocai.jrt.utils.UnionPayCallbackUtils;

/**
 * 支付回调控制器
 * 
 * @author linbaolu
 * @date 2015-7-27 19:26:12
 */
@Controller
@RequestMapping("/pay")
public class PayAction extends GenericAction<PaySerial> {
	private static final Logger LOGGER = LoggerFactory.getLogger(PayAction.class);

	@Inject
	private PaySerialService paySerialServiceImpl;
	@Inject
	private RiskDisclosureService riskDisclosureServiceImpl;
	@Inject
	private SettingService settingServiceImpl;
	@Inject
	private ContactService contactServiceImpl;
	@Inject
	private OrdersService ordersServiceImpl;
	@Resource(name = "taskExecutor")
	private TaskExecutor taskExecutor;

	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss"), true));
		binder.registerCustomEditor(int.class, new IntEditor());
		binder.registerCustomEditor(long.class, new LongEditor());
		binder.registerCustomEditor(double.class, new DoubleEditor());
		binder.registerCustomEditor(String.class, new StringEditor());
	}

	/**
	 * 执行实际的新增操作
	 * 
	 * @param model
	 *            要新增的数据
	 * @return 新增页面逻辑视图
	 */
	@ResponseBody
	@RequestMapping("/callback")
	public JsonBean callback(PaySerial paySerial, String tokenId) {
		JsonBean jsonBean = null;
		try {
			// 发起请求的参数,以后直接用AOP代替
			LOGGER.info("request payCallback, param=[{}]", JSON.toJSONString(paySerial));

			jsonBean = paySerialServiceImpl.callback(paySerial, tokenId);

			// 生成电子合同
			try {
				String orderId = paySerial.getOrderId();
				Orders orderParam = new Orders();
				orderParam.setOrderId(orderId);
				Orders order = ordersServiceImpl.unique(orderParam);

				Setting setting = new Setting();
				setting.setKeyName("orderRevisit");
				setting.setOrgId(order.getOrgId());
				Setting getSetting = settingServiceImpl.unique(setting);

				// 0-不需要回访主流程继续
				if ("0".equals(getSetting.getKeyValue())) {

					taskExecutor.execute(new ContactThread(contactServiceImpl,
							riskDisclosureServiceImpl, orderId));
				}

			} catch (Exception e) {
				LOGGER.error("createContact error, msg=[{}]", e.getMessage());
			}

			LOGGER.info("request payCallback, jsonBean=[{}]", JSON.toJSONString(jsonBean));

			if (jsonBean.getCode() == 1) {
				jsonBean.setMessage("回调成功！");
				LOGGER.info("request payCallback success");
			}

		} catch (Exception e) {
			jsonBean.setCode(0);
			jsonBean.setMessage("回调失败！");
			LOGGER.error("request payCallback error,msg = [{}]", e.getMessage());
		}

		return jsonBean;
	}

	@ResponseBody
	@RequestMapping("/callbackOfficial")
	public CallbackResJsonBean callbackOfficial(String params, String signature) {
		CallbackResJsonBean jsonBean = new CallbackResJsonBean();

		try {
			// 记录参数
			LOGGER.info("UnionPay request callbackOfficial, params=[{}], signature=[{}]", params,
					signature);
			jsonBean.setMerchantRecMsgProcessState(1);
			jsonBean.setMessage("回调成功,回调参数详见log日志");
			jsonBean.setCode(1);

			// 验证银联回调参数
			boolean verify = UnionPayCallbackUtils.verify(params.getBytes(), signature);
			if (!verify) {
				jsonBean.setCode(0);
				jsonBean.setMessage("回调失败！签名验证错误");
				jsonBean.setMerchantRecMsgProcessState(0);
				LOGGER.error("回调失败！签名验证错误");
				return jsonBean;
			}

			// 解密银联回调，并解密成json字符串
			byte[] desByte = UnionPayCallbackUtils.desEdeEcbPkcs5Decrypt(
					UnionPayCallbackUtils.hexString2ByteArr(params),
					UnionPayCallbackUtils.hexString2ByteArr(PropsUtils.get("payCallback.deskey")));

			String jsonString = new String(desByte, "UTF-8");
			LOGGER.info("UnionPay callback's paramter object string, jsonString=[{}]", jsonString);
			CallBackReqBean callBackReqBean = JSON.parseObject(jsonString, CallBackReqBean.class);

			// 发起请求的参数,以后直接用AOP代替
			LOGGER.info("request payCallback, param=[{}]", JSON.toJSONString(callBackReqBean));

			String tokenId = "jG8MJPZFG_tQ77YKbsz7WR7abxEpb2CAqnmBQad-cgC8diabq_mxxQ";
			jsonBean = paySerialServiceImpl.callback(callBackReqBean, tokenId);

			// 生成电子合同
			try {
				String orderId = callBackReqBean.getOrderId();
				Orders orderParam = new Orders();
				orderParam.setOrderId(orderId);
				Orders order = ordersServiceImpl.unique(orderParam);

				Setting setting = new Setting();
				setting.setKeyName("orderRevisit");
				setting.setOrgId(order.getOrgId());
				Setting getSetting = settingServiceImpl.unique(setting);

				// 0-不需要回访主流程继续
				if ("0".equals(getSetting.getKeyValue())) {

					taskExecutor.execute(new ContactThread(contactServiceImpl,
							riskDisclosureServiceImpl, orderId));
				}

			} catch (Exception e) {
				LOGGER.error("createContact error, msg=[{}]", e.getMessage());
			}

			LOGGER.info("request payCallback, jsonBean=[{}]", JSON.toJSONString(jsonBean));

			if (jsonBean.getCode() == 1) {
				jsonBean.setMessage("回调成功！");
				jsonBean.setMerchantRecMsgProcessState(1);
				LOGGER.info("request payCallback success");
			}
		} catch (Exception e) {
			jsonBean.setCode(0);
			jsonBean.setMessage("回调失败！");
			jsonBean.setMerchantRecMsgProcessState(0);
			LOGGER.error("request payCallback error,msg = [{}]", e.getMessage());
		}

		return jsonBean;
	}
}
